﻿using JsonModel;
using Microsoft.VisualBasic;
using MyBot.Api;
using MyBot.Expansions.Bot;
using MyBot.Models.MessageModels;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.X509.Qualified;
using RgChannelBot;
using System.Diagnostics;
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using static System.Net.Mime.MediaTypeNames;

#if false
#else
Console.WriteLine("------------超电磁炮服务器--频道机器人------------");
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    if (e.ExceptionObject is Exception ex)
    {
        File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "exception.log"), ex.ToString());
    }
    Console.Clear();
    Process.Start("RgChannelBot.exe");
}

Directory.CreateDirectory(Path.Combine(Environment.CurrentDirectory, "Temp"));
if (!File.Exists(Path.Combine(Environment.CurrentDirectory, "config.json")))
{
    string def = JsonConvert.SerializeObject(new Config(), Formatting.Indented);
    File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "config.json"), def);
    Log.RawOutput("配置", "没有检测到配置文件，已创建一个默认文件，请前往修改机器人信息 [任意键退出]", ConsoleColor.DarkYellow);
    Console.Read();
    return;
}
Config? c;
try
{
    c = JsonConvert.DeserializeObject<Config?>(File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "config.json")));
    if (c == null)
    {
        Log.RawOutput("配置", "无法读取配置文件！返回了一个null值，请检查格式 [任意键退出]", ConsoleColor.Red);
        Console.Read();
        return;
    }
}
catch (Exception e)
{
    Log.Error("读取配置文件时出现异常: " + e);
    Console.Read();
    return;
}
Rg.Config = c;
Rg.ConnectionString = $"data source={c.DatabaseConfig.IpAddress};port={c.DatabaseConfig.Port};" +
    $"database={c.DatabaseConfig.Database};user id={c.DatabaseConfig.UserName};password={c.DatabaseConfig.Password};SslMode=None";
QQChannelApi api = new(c.BotData);
Rg.Api = api;
api.UseBotIdentity();
ChannelBot bot = new(api);
bot.UsePrivateBot();
bot.RegisterGuildsEvent().
    RegisterGuildMembersEvent().
    RegisterUserMessageEvent().
    RegisterAtMessageEvent().
    RegisterChatEvent().
    RegisterForumEvent().
    RegisterAuditEvent().
    RegisterMessageReactionEvent().
    EnableUserMessageTriggerCommand();
bot.OnConnected += () =>
{
    Log.Info("已连接至腾讯官方平台");
};
bot.AuthenticationSuccess += () =>
{
    Log.RawOutput("成功", "身份认证完毕，机器人已上线", ConsoleColor.Green);
};
bot.OnError += (e) =>
{
    Log.Error(e.ToString());
};
Rg.Bot = bot;
await bot.OnlineAsync();
bot.ReceivedChatGroupMessage += async (message) =>
{
   if (message.Content.Trim() == "/cx")
    {
        try
        {
            if (Rg.uses.TryGetValue(message.Author.MemberOpenId, out var last))
            {
                if ((DateTime.Now - last).TotalMinutes < 30)
                {
                    await Rg.Api.GetChatMessageApi().SendGroupMessageAsync(message.GroupOpenId, "本群机器人针对每名用户查询频率限制为30分钟，请等待后重试\n推荐加入本服务器QQ频道来使用全功能机器人\n频道链接请查阅群公告", passiveMsgId: message.Id);
                    return;
                }
            }
            if (Rg.Config.Servers.Count == 0)
            {
                await Rg.Api.GetChatMessageApi().SendGroupMessageAsync(message.GroupOpenId, "当前没有服务器，请联系技术人员添加服务器", passiveMsgId: message.Id);
                return;
            }
            ExecutionRequest er = new()
            {
                Request = Request.StatusQuery
            };
            string msg = JsonConvert.SerializeObject(er);
            List<Task<string>> tasks = new();
            List<string> server_name = new();
            foreach (var con in Rg.Config.Servers)
            {
                tasks.Add(con.SendMsg(msg));
                server_name.Add(con.Name);
            }
            var result = (await Task.WhenAll(tasks.ToArray())).ToList();
            int id = 0;
            MessageMarkdown md = new()
            {
                Params = new List<MessageMarkdownParams>(),
                CustomTemplateId = "102069299_1720617765"
            };
            for (int i = 0; i < result.Count && i < 8; i++)
            {
                id++;
                string val = $"【{server_name[id - 1]}】 %PLAYER% / %MAX% (%STATUS%)";
                if (result[i] == "Offline" || result[i] == "Unknown")
                {
                    md.Params.Add(new MessageMarkdownParams($"server{i}",
                        val.Replace("%PLAYER%", "N").Replace("%MAX%", "A").Replace("%STATUS%", "离线")));
                    continue;
                }
                ServerData? sd = JsonConvert.DeserializeObject<ServerData>(result[i]);
                if (sd == null)
                {
                    md.Params.Add(new MessageMarkdownParams($"server{i}",
                        val.Replace("%PLAYER%", "N").Replace("%MAX%", "A").Replace("%STATUS%", "离线")));
                    continue;
                }
                md.Params.Add(new MessageMarkdownParams($"server{i}",
                val.Replace("%PLAYER%", sd.Players.ToString()).Replace("%MAX%", sd.MaxPlayers.ToString()).Replace("%STATUS%", sd.RoundTime == -1 ? "等待玩家中" : $"已开局{sd.RoundTime}分钟")));
            }
            if (!Rg.uses.ContainsKey(message.Author.MemberOpenId))
                Rg.uses.Add(message.Author.MemberOpenId, DateTime.Now);
            else
                Rg.uses[message.Author.MemberOpenId] = DateTime.Now;
            await Rg.Api.GetChatMessageApi().SendGroupMessageAsync(message.GroupOpenId, "", ChatMessageType.Markdown, markdown: md, passiveMsgId: message.Id);
            return;
        }
        catch (Exception e)
        {
            Log.Error(e);
        }
    }
};
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
    if (type.GetInterfaces().Contains(typeof(IStepCommand)))
    {
        IStepCommand? cmd = (IStepCommand?)Activator.CreateInstance(type);
        if (cmd == null)
            continue;
        bot.RegisterStepCommand(cmd.Command, async (d, state) =>
        {
            if (cmd.BotChannelRestricted && Rg.Config.BotChannelId != d.ChannelId && !cmd.AdminChannelOnly && Rg.Config.AdminChannelId != d.ChannelId)
            {
                await Rg.Api.GetReactionApi().AddReactionAsync(d.ChannelId, d.MessageId, new Emoji() { Type = 1, Id = "322" });
                return;
            }
            var member = await Rg.Api.GetMemberApi().GetInfoAsync(d.GuildId, d.Sender.Id);
            int permission = 0;
            foreach (var role in member.Roles.Where(x => Rg.Config.GroupPermissions.ContainsKey(x)))
                permission = Math.Max(Rg.Config.GroupPermissions[role], permission);
            if (permission < cmd.RequiredPermission)
            {
                await Rg.Api.GetMessageApi().SendMessageAsync(d.ChannelId, "你没有权限使用此指令！", referenceMessageId: d.MessageId, passiveMsgId: d.MessageId);
                return;
            }
            foreach (var ac in cmd.Actions)
                ac(d, state);
        });
        Log.RawOutput("命令", $"已注册步骤命令：{cmd.Command}", ConsoleColor.Blue);
    }
    else if (type.GetInterfaces().Contains(typeof(INormalCommand)))
    {
        INormalCommand? cmd = (INormalCommand?)Activator.CreateInstance(type);
        if (cmd == null)
            continue;
        bot.RegisterCommand(cmd.Command, async (d) =>
        {
            if (cmd.BotChannelRestricted && Rg.Config.BotChannelId != d.ChannelId && !cmd.AdminChannelOnly && Rg.Config.AdminChannelId != d.ChannelId)
            {
                await Rg.Api.GetReactionApi().AddReactionAsync(d.ChannelId, d.MessageId, new Emoji() { Type = 1, Id = "322" });
                return;
            }
            var member = await Rg.Api.GetMemberApi().GetInfoAsync(d.GuildId, d.Sender.Id);
            int permission = 0;
            foreach (var role in member.Roles.Where(x => Rg.Config.GroupPermissions.ContainsKey(x)))
                permission = Math.Max(Rg.Config.GroupPermissions[role], permission);
            if (permission < cmd.RequiredPermission)
            {
                await Rg.Api.GetMessageApi().SendMessageAsync(d.ChannelId, "你没有权限使用此指令！", referenceMessageId: d.MessageId, passiveMsgId: d.MessageId);
                return;
            }
            await cmd.Execute(d);
        });
        Log.RawOutput("命令", $"已注册普通命令：{cmd.Command}", ConsoleColor.Blue);
    }
}
Log.Info("开始侦听..");
Thread.Sleep(1000);
while (true)
{
    Console.Write(">");
    string? cmd = Console.ReadLine();
    if (cmd != null)
    {
        string[] array = cmd.Split(' ');
        switch (array[0])
        {
            case "quit":
                {
                    string def = JsonConvert.SerializeObject(Rg.Config, Formatting.Indented);
                    File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "config.json"), def);
                    return;
                }
            case "bindguild":
                {
                    Rg.CurrentBindingStatus = Binding.Guild;
                    var key = new Random().Next(0, 9999).ToString();
                    Rg.Bindkey = key;
                    Console.WriteLine("请在你要绑定的频道的任意子频道并输入该代码：" + key);
                    break;
                }
            case "reloadconfig":
                {
                    try
                    {
                        c = JsonConvert.DeserializeObject<Config?>(File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "config.json")));
                        if (c == null)
                        {
                            Log.RawOutput("配置", "无法读取配置文件！返回了一个null值，请检查格式", ConsoleColor.Red);
                            break;
                        }
                        Rg.Config = c;
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                    }
                    break;
                }
            case "rolelist":
                {
                    var (roles, limit) = await Rg.Api.GetChannelRoleApi().GetRolesAsync(Rg.Config.GuildId);
                    Console.WriteLine("所有权限组：");
                    foreach (var role in roles)
                    {
                        Console.WriteLine($"【{role.Name}】 ({role.Id}) <{Convert.ToString(role.Color, 16)}> [{role.Number}/{role.MemberLimit}]");
                    }
                    break;
                }
            case "channellist":
                {
                    var channels = await Rg.Api.GetChannelApi().GetChannelsAsync(Rg.Config.GuildId);
                    Console.WriteLine("所有子频道：");
                    foreach (var x in channels)
                    {
                        Console.WriteLine($"[{x.Id}] -> [{x.ParentId}] {x.Name} ({x.PrivateType}) {x.Type} {x.SpeakPermission}");
                    }
                    break;
                }
            case "getchannel":
                {
                    var channel = await Rg.Api.GetChannelApi().GetInfoAsync(array[1]);
                    foreach (var x in channel.PrivateUserIds)
                    {
                        Console.WriteLine(x);
                    }
                    break;
                }
            case "tickets":
                {
                    foreach (var x in ReportCommand.Tickets)
                    {
                        Console.WriteLine($"[{x.Id}] {x.Issuer.UserName}({x.Issuer.Id}) - {x.Closed}");
                    }
                    break;
                }
            case "boom":
                {
                    throw new InvalidOperationException("你好，你要的BOOM");
                }
        }
    }
}
#endif